package common

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

// GetCurrentUserID 从上下文中获取当前用户ID
func GetCurrentUserID(c *gin.Context) (int64, error) {
	userID, exists := c.Get("user_id")
	if !exists {
		return 0, fmt.Errorf("user_id not found in context")
	}

	// 类型断言
	if id, ok := userID.(int64); ok {
		return id, nil
	}

	// 如果类型不匹配，尝试转换
	if id, ok := userID.(float64); ok {
		return int64(id), nil
	}

	return 0, fmt.Errorf("invalid user_id type in context")
}

// GetCurrentUsername 从上下文中获取当前用户名
func GetCurrentUsername(c *gin.Context) (string, error) {
	username, exists := c.Get("username")
	if !exists {
		return "", fmt.Errorf("username not found in context")
	}

	if name, ok := username.(string); ok {
		return name, nil
	}

	return "", fmt.Errorf("invalid username type in context")
}

// GetCurrentRoleID 从上下文中获取当前用户角色ID
func GetCurrentRoleID(c *gin.Context) (int64, error) {
	roleID, exists := c.Get("role_id")
	if !exists {
		return 0, fmt.Errorf("role_id not found in context")
	}

	if id, ok := roleID.(int64); ok {
		return id, nil
	}

	if id, ok := roleID.(float64); ok {
		return int64(id), nil
	}

	return 0, fmt.Errorf("invalid role_id type in context")
}

// GetCurrentUserClaims 从上下文中获取当前用户声明信息
func GetCurrentUserClaims(c *gin.Context) (map[string]interface{}, error) {
	claims, exists := c.Get("claims")
	if !exists {
		return nil, fmt.Errorf("claims not found in context")
	}

	if userClaims, ok := claims.(map[string]interface{}); ok {
		return userClaims, nil
	}

	return nil, fmt.Errorf("invalid claims type in context")
}

// RequireCurrentUserID 获取当前用户ID，如果失败则返回错误响应
func RequireCurrentUserID(c *gin.Context) (int64, bool) {
	userID, err := GetCurrentUserID(c)
	if err != nil {
		Error(c, http.StatusUnauthorized, "user_id_not_found", err)
		return 0, false
	}
	return userID, true
}

// RequireCurrentUsername 获取当前用户名，如果失败则返回错误响应
func RequireCurrentUsername(c *gin.Context) (string, bool) {
	username, err := GetCurrentUsername(c)
	if err != nil {
		Error(c, http.StatusUnauthorized, "username_not_found", err)
		return "", false
	}
	return username, true
}
